package org.streets.eis.ext.rbac.pages;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.streets.commons.util.GUID;
import org.streets.database.Limits;
import org.streets.database.SQLBatcher;
import org.streets.database.SQLConnection;
import org.streets.eis.component.ChangedNotifyType;
import org.streets.eis.component.grid.BooleanColumn;
import org.streets.eis.component.grid.LinkColumn;
import org.streets.eis.component.grid.TableList;
import org.streets.eis.component.model.MemoryTableModel;
import org.streets.eis.component.model.MenuItem;
import org.streets.eis.component.tree.Node;
import org.streets.eis.entity.Role;
import org.streets.eis.ext.rbac.component.ModuleTree;
import org.streets.eis.ext.rbac.entities.RolePermission;
import org.streets.eis.ext.rbac.services.RBACAuthorizer;
import org.streets.eis.pages.BasePage;
import org.streets.eis.types.PermitTarget;

import com.inmethod.grid.IGridColumn;
import com.inmethod.grid.column.PropertyColumn;

public class FuncPermissionPanel extends Panel{

	private static final long serialVersionUID = 1L;

	@Inject
	private SQLConnection conn;
	
	@Inject
	private RBACAuthorizer authorizer;
	
	private ModuleTree moduleTree; 
	
	private TableList<RolePermission> selected;
	
	private MemoryTableModel<RolePermission> selectedModel;
	
	@SuppressWarnings("unchecked")
	public FuncPermissionPanel(String id,final Role role) {
		super(id);
		Form form = new Form("form"){
			private static final long serialVersionUID = 1L;
			protected void onSubmit(){
				authorizer.removeRolePermissions(role, PermitTarget.FUNC);
				String permissionSql = "INSERT INTO EIS_ROLE_PERMISSIONS(ID,ROLE_ID,PERM_TARGET,TARGET_VALUE,DISPLAY_TEXT,INC_CHILD) VALUES(?,?,?,?,?,?)";
				SQLBatcher batcher = conn.prepare(permissionSql);								
				for(IModel<RolePermission> model : selected.getRowModels()){
					RolePermission p = model.getObject();
					batcher.add(new Object[]{p.id,p.roleId,p.permTarget,p.targetValue,p.displayText,p.incChild});
				}
				batcher.execute();
				authorizer.generateRolePermissions(role, PermitTarget.FUNC);
			}
		};		
		add(form);
		
		form.add(new AjaxLink("refresh") {		
			private static final long serialVersionUID = 1L;
			@Override
			public void onClick(AjaxRequestTarget target) {			
				generateTableModel(role);
				selected.setDefaultModelObject(selectedModel);
				selected.ajaxRefresh();
			}
		});
		
		form.add(moduleTree=createModuleTree("moduleTree",role));
		moduleTree.setPreSelectNode(false);
		
		selectedModel = generateTableModel(role);
		selected = new TableList<RolePermission>("selected",selectedModel,generateColumns());
		form.add(selected);
		
		selected.setAllowSelectMultiple(true);	
		selected.setClickRowToSelect(false);
		selected.setClickRowToDeselect(false);
		selected.setShowNoRecordsBar(false);
		selected.setShowPagingBar(false);
		selected.setEditAllRowsOnInitialization(true);
		selected.setCanCancelEdit(false);		
	}
	
	private ModuleTree createModuleTree(String id ,final Role role){
		return new ModuleTree(id){
			private static final long serialVersionUID = 1L;
			@Override
			protected void onNodeLabelClicked(Node<MenuItem> node, BaseTree tree, AjaxRequestTarget target){
				if (role == null){
					((BasePage)getPage()).getMessageBox().alert("请选择要设置权限的角色！");
					return;
				}
				for (Iterator<RolePermission> iter=selectedModel.iterator();iter.hasNext();){
					RolePermission tmp = iter.next();
					if (tmp.targetValue.equals(node.getObject().getId())){						
						return;
					}
				}
				RolePermission permission = new RolePermission();
				permission.id = GUID.nextUUID();
				permission.incChild = false;
				permission.permTarget = PermitTarget.FUNC.getName();
				permission.roleId = role.getId();
				permission.displayText = node.getObject().getDisplayText();
				permission.targetValue = node.getObject().getId();				
				selectedModel.addRow(permission);
				selected.ajaxRefresh();
			}			
		};
	}

	private MemoryTableModel<RolePermission> generateTableModel(Role role){
		List<RolePermission> permissions;
		if (role == null) {
			permissions = new ArrayList<RolePermission>();
		} else {
			String permissionSql = String.format("SELECT * FROM EIS_ROLE_PERMISSIONS WHERE ROLE_ID='%s' AND PERM_TARGET='%s'",role.getId(),PermitTarget.FUNC.getName());
			permissions = conn.query(permissionSql, RolePermission.class, Limits.none());
			
		}		
		selectedModel = new MemoryTableModel<RolePermission>(permissions);
		return selectedModel;
	}
	
	private List<IGridColumn> generateColumns(){
		List<IGridColumn> columns = new ArrayList<IGridColumn>();
		
		columns.add(new PropertyColumn(Model.of("模块名称"),"displayText","DISPLAY_TEXT").setInitialSize(120));
		
		columns.add(new BooleanColumn(Model.of("是否包括下级"),"incChild","INC_CHILD"){
			private static final long serialVersionUID = 1L;
			
			@Override
			public ChangedNotifyType getChangedNotifyType() {
				return ChangedNotifyType.AJAX;
			}
			protected void onAjaxSelectionChanged(CheckBox component,Boolean checked,AjaxRequestTarget target) {
				RolePermission permission = (RolePermission) selected.findParentRow(component).getDefaultModelObject();
				selectedModel.findRow(permission).incChild = checked;				
			}
			
		}.setInitialSize(90));
		
		columns.add(new LinkColumn("delete",Model.of("删除")){
			private static final long serialVersionUID = 1L;
			@Override
			protected void onLinkClicked(IModel<?> rowModel,AjaxRequestTarget target){
				selectedModel.removeRow((RolePermission)rowModel.getObject());
				selected.ajaxRefresh();
			}			
		});
		
		return columns;
	}
	
}
